/************************************************************************
 *File Name: getfile.c
 *Author: wsy
 *Created Time: 2023年06月20日 星期二 21时32分33秒
 *Describtion: 
 ************************************************************************/
#include "transfile.h"
#include <func.h>

bool isExist(const char* filename, const char* virtual_path) 
{
    // 打开目录流
    DIR* pdir = opendir(virtual_path);
    struct dirent* pdirent;
    while((pdirent = readdir(pdir)) != NULL) 
    {
        if(strcmp(pdirent->d_name, filename) == 0) 
        {
            return 1;
        }
    }

    return 0;
}

int getFile(const char* filename, int netfd, const char* virtual_path)
{
    // 检查文件是否存在
    if(isExist(filename, virtual_path) != 1) 
    {
        //文件不存在
        return -1;
    }

    // 文件存在
    // 拼接当前虚拟目录和文件名
    char filepath[1024];
    strcpy(filepath, virtual_path);
    strcat(filepath, "/");
    strcat(filepath, filename);


    // 初始化小火车
    Train train;
    bzero(&train, sizeof(train));

    // 接收offset
    off_t offset;
    int length;
    recvN(netfd, &length, sizeof(length));
    recvN(netfd, &offset, length);

    // 检查文件是否过大
    int fd = open(filepath, O_RDWR);
    struct stat statbuf;          
    fstat(fd, &statbuf);
    close(fd);
    if(statbuf.st_size >= BIG_FILE_SIZE)
    {
        // 是大文件
        printf("big file\n");
        int ret = mmapSendFile(filename, netfd, offset);
        if(ret != 0) 
        {
            return -1;
        }
    }
    else
    {
        // 是小文件
        // 设置offset， 传输文件内容
        printf("small file\n");
        fd = open(filepath, O_RDWR);
        lseek(fd, offset, SEEK_SET);

        while(1) 
        {
            bzero(&train, sizeof(train));
            train.length = read(fd, train.data, sizeof(train.data));
            send(netfd, &train, sizeof(int) + train.length, MSG_NOSIGNAL);
            if(train.length == 0)
            {
                break;
            }
        }
        close(fd);
    }

    return 0;
}

int recvN(int netfd, void* buf, int length)
{
    int total = 0;      // 已经recv的字节数
    char* p = (char*)buf;
    while(total < length) 
    {
        int ret = recv(netfd, p + total, length - total, 0);
        if(ret == 0) 
        {
            return -1;
        }
        total += ret;
    }

    return 0;
}

int putFile(const char* filename, int netfd, const char* virtual_path) 
{
    // 拼接当前虚拟目录和文件名, 打开文件
    char filepath[1024];
    strcpy(filepath, virtual_path);
    strcat(filepath, "/");
    strcat(filepath, filename);
    int fd = open(filepath, O_RDWR | O_CREAT | O_TRUNC, 0666);

    // 客户端发来小火车, 服务端接收并写入本地
    char buf[1024] = {0};
    int length;
    while(1)
    {
        recvN(netfd, &length, sizeof(length));
        if(length == 0) 
        {
            break;
        }
        bzero(buf, sizeof(buf));
        recvN(netfd, buf, length);
        write(fd, buf, length);
    }

    close(fd);

    return 0;
}
